You are a
professional robber planning to rob houses along a street. Each house has a
certain amount of money stashed away. The only constraint stopping you from
robbing each of them is that adjacent houses have a security system connected,
and it will automatically contact the police if two adjacent houses are broken
into on the same night.
Given a list
of non-negative integers representing the amount of money in each house,
determine the maximum amount of money you can rob tonight without alerting the
police.
Input. The first line contains the number of houses n (1 ≤ n ≤ 106). The second line contains n non-negative integers a1, a2, ..., an,
where ai is the amount of
money that can be taken from the i-th
house.
Output. Print the maximum sum you
can steal tonight without triggering a police alert.
Sample
input |
Sample
output |
5 6 1 2 10 4 |
16 |
dynamic programming
Algorithm analysis
Let’s number the houses
starting from the first index (the i-th
house contains ai money). Let
f(i) be the maximum amount of loot after
robbing houses from 1 to the i-th.
Then f(1) = a1, f(2) = max(a1, a2).
When computing f(i), consider two cases:
·
If the i-th house is
robbed, then the (i – 1)-th house cannot
be robbed. In this case, the profit will be f(i – 2) + ai.
·
if the i-th house is
not robbed, the profit will be f(i –
1).
Thus,
f(i) = max(f(i – 2) + ai, f(i – 1))
Let’s store the values of
f(i) in the array res. The answer to
the problem will be the value f(n) =
res[n].
Example
Let’s consider the
computation of f(3). If we don’t rob the 3-rd house, the profit will be f(2) = 6. If the 3-rd house is robbed, we can rob the first house,
gaining a profit of f(1) = 6, plus the profit from robbing the 3-rd house, which is 2 (the total profit will be 6 + 2 = 8).
Now, let’s consider the
computation of f(4). If we don’t rob the 4-th house, the profit will be f(3) = 8. If the 4-th house is robbed, we can rob the first two houses,
gaining a profit of f(2) = 6, plus the profit from robbing the 4-th house, which is 10 (the total profit will be 6 + 10 = 16).
Exercise
Compute the values of f(i) for the following input data:
Algorithm realization
Declare the input array à and the resulting array res.
#define MAX 1000001
long long
a[MAX], res[MAX];
Read the input data.
scanf("%d",&n);
for(i = 1; i <= n; i++)
scanf("%lld",&a[i]);
Compute the answer res1
for one house, and res2
for two houses.
res[1] = a[1];
if (n > 1) res[2] = max(a[1],a[2]);
Compute the answers for the remaining houses.
for(i = 3; i <= n; i++)
res[i] = max(res[i - 2] + a[i], res[i - 1]);
Print the answer.
printf("%lld\n",res[n]);
Java realization
import java.util.*;
class Main
{
static long a[] = new long[1000001];
static long res[] = new long[1000001];
public static void main(String[] args)
{
Scanner con = new
Scanner(System.in);
int n = con.nextInt();
for(int i = 1; i <= n; i++)
a[i] = con.nextInt();
res[1] = a[1];
if (n > 1) res[2] = Math.max(a[1],a[2]);
for(int i = 3; i <= n; i++)
res[i] = Math.max(res[i - 2] + a[i], res[i - 1]);
System.out.println(res[n]);
con.close();
}
}
Python realization
Read the input data.
n = int(input())
lst = list(map(int,input().split()))
Initialize the list dp.
dp = [0] * len(lst)
Compute the answer dp0 for one house, and dp1 for two houses.
dp[0] = lst[0]
if (n > 1): dp[1] = max(lst[0], lst[1])
Compute the answers for the remaining houses.
for i in range(2, len(lst)):
dp[i] = max(dp[i-1], dp[i-2] + lst[i])
Print the answer.
print(dp[-1])